<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="1000" v-loading="formLoading">
    <el-form ref="formRef" :inline="true" :model="formData" :rules="formRules" label-width="120px" class="form-inline">
      <el-form-item label="测试计划名称:" prop="name">
        <el-input v-model="formData.name" placeholder="请输入测试计划名称" clearable />
      </el-form-item>
      <el-form-item label="产品版本号:" prop="versionId">
        <el-select v-model="formData.versionId" filterable clearable placeholder="请选择版本"
          :disabled="formType == 'update'">
          <el-option v-for="item in versionList" :key="item.id" :label="item.versionName" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="提测版本:" prop="testFormId">
        <el-select v-model="formData.testFormId" filterable clearable placeholder="请选择提测单"
          :disabled="formType == 'update'" @change="changeCommitVersion">
          <el-option v-for="item in commitList" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="计划开始时间:" prop="startTime">
        <el-date-picker v-model="formData.startTime" type="datetime" placeholder="请选择计划开始时间"
          format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" @change="changeStartDate" />
      </el-form-item>
      <el-form-item label="计划结束时间:" prop="endTime">
        <el-date-picker v-model="formData.endTime" type="datetime" placeholder="请选择计划结束时间" format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss" @change="changeEndDate" />
      </el-form-item>
      <el-form-item label="描述:" prop="descr" style="width: 100%">
        <el-input v-model="formData.descr" placeholder="请输入描述" type="textarea" rows="5" />
      </el-form-item>
    </el-form>
    <UseCase ref="useCase" @node-success="handleNodeSuccess" @case-success="handleCaseSuccess" :caseIds="caseIds"
      :suiteIds="suiteIds" :type="formType" @test-user-success="handleTestUserSuccess" />
    <template #footer>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script lang="ts" setup>
import * as TestPlanApi from '@/api/testPlan'
import { getPage } from '@/api/test'
import { getTestboxTree, getTestformList } from '@/api/usecase'
import UseCase from './component/UseCase.vue'
import { useAppStore } from '@/store/modules/app'
import { getDemandList } from '@/api/demand'
import { formatMsToLocalTime } from '@/utils/formatTime'
import { flattenTree } from '@/utils/tree'
defineOptions({ name: 'UpdateUseCasePlan' })
const appStore = useAppStore()
const projectId = computed(() => appStore.getSelectProject)
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false)
const formData = ref({} as any) //表单数据
const formType = ref('')
const versionList = ref([] as any) // 版本下拉
const commitList = ref([] as any) // 提测下拉
const nodeSelectList = ref([] as any) // 树结构（用例集）选中集合
const caseList = ref([] as any) // 用例选中集合
const suiteIds = ref([] as any) // 编辑回显用例集ids
const caseIds = ref([] as any) // 编辑回显用例ids
const planList = ref([] as any) // 测试计划列表
const formRules = reactive({
  name: [{ required: true, message: '测试计划名称不能为空', trigger: 'blur' }],
  versionId: [{ required: true, message: '版本不能为空', trigger: 'change' }],
  testFormId: [{ required: true, message: '提测单编号不能为空', trigger: 'change' }],
  startTime: [{ required: true, message: '开始时间不能为空', trigger: 'change' }],
  endTime: [{ required: true, message: '结束时间不能为空', trigger: 'change' }]
})

const formRef = ref() // 表单 Ref
const dataSource = ref([] as any)
const testUserObj = ref({} as any) // 测试人员选择集合

/** 打开弹窗 */
const open = async (type, id) => {
  resetForm()
  getTreeList()
  getVersionList()
  getCommitList()
  getPlanList()
  if (type == 'update' && id) {
   await getInfo(id)
  }
  dialogVisible.value = true
  formType.value = type
  dialogTitle.value = t('action.' + type)
}
// 获取计划下拉
const getPlanList = async () => {
  formLoading.value = true
  try {
    let data = await TestPlanApi.getPlanList({ projectId: projectId.value })
    if (!data) return
    planList.value = data
  } finally {
    formLoading.value = false
  }
}
const changeCommitVersion = (val) => {
  const isHas = planList.value.some((p) => p.testFormId == val)
  if (isHas) {
    message.warning('该提测版本已关联测试计划')
    formData.value.testFormId = ''
  }
}
// 日期校验
const changeStartDate = (val) => {
  const endTime = new Date(formData.value.endTime.replace(/-/g, '/'))
  const date = new Date(val.replace(/-/g, '/'))
  if (date.getTime() + 5000 < Date.now()) {
    message.warning('开始时间不能早于当前时间')
    formData.value.startTime = ''
    return
  }
  if (formData.value.endTime && date.getTime() > endTime.getTime()) {
    message.warning('开始时间不能晚于结束时间')
    formData.value.startTime = ''
    return
  }
}
const changeEndDate = (val) => {
  const startTime = new Date(formData.value.startTime.replace(/-/g, '/'))
  const date = new Date(val.replace(/-/g, '/'))
  if (date.getTime() + 5000 < Date.now()) {
    message.warning('结束时间不能早于当前时间')
    formData.value.endTime = ''
    return
  }
  if (formData.value.startTime && date.getTime() < startTime.getTime()) {
    message.warning('结束时间不能早于开始时间')
    formData.value.endTime = ''
    return
  }
}

// 详情
const getInfo = async (id) => {
  suiteIds.value = []
  caseIds.value = []
  let data = await TestPlanApi.getPlanInfo({ id })
  formData.value = data
  formData.value.startTime = formatMsToLocalTime(data.startTime)
  formData.value.endTime = formatMsToLocalTime(data.endTime)
  suiteIds.value = data.suiteIds
  caseIds.value = data.caseIds
}
// 获取版本
const getVersionList = async () => {
  let data = await getDemandList({
    pageNo: 1,
    pageSize: 100,
    projectId: projectId.value
  })
  versionList.value = data.list
}
// 获取提测单
const getCommitList = async () => {
  commitList.value = []
  let data = await getTestformList({
    projectId: projectId.value
  })
  commitList.value = data.map((item) => {
    return {
      label: `${item.version.versionName}版本-${item.rounds}轮次`,
      value: item.id
    }
  })
}
/** 重置表单 */
const resetForm = () => {
  formData.value = {
    name: '',
    versionId: '',
    testFormId: '',
    startTime: '',
    endTime: '',
    descr: '',
    projectId: projectId.value
  }
  formRef.value?.resetFields()
  suiteIds.value = []
  caseIds.value = []
}

defineExpose({ open })

/** 提交表单 */
const emit = defineEmits(['success'])
const submitForm = async () => {
  // 校验表单
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  // 提交请求
  formLoading.value = true
  try {
    const data = formData.value
    if (formType.value === 'create') {
      await TestPlanApi.createPlan({ ...data, ...handle(data) })
      message.success(t('common.createSuccess'))
    } else {
      await TestPlanApi.updatePlan({ ...data, ...handle(data) })
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}
// 用例集节点选择
const handleNodeSuccess = (list) => {
  nodeSelectList.value = list
}
// 用例选择
const handleCaseSuccess = (list) => {
  caseList.value = list
}
// 获取用例集
const getTreeList = async () => {
  let data = await getTestboxTree({ projectId: projectId.value })
  let temp = data ? [data] : []
  dataSource.value = flattenTree(temp)
}
// 测试人员选择
const handleTestUserSuccess = (obj) => {
  testUserObj.value = obj
}
// 创建、更新计划 请求参数处理
const handle = (params) => {
  let planCases = [], planSuites = []
  if (nodeSelectList.value.length) {
    planSuites = nodeSelectList.value.map((node) => {
      return {
        testSuiteId: node.id,
        parentId: node.parent
      }
    })
  } else {
    planSuites = params.suiteIds.map((node) => {
      const parent = dataSource.value.find(d => d.id == node)?.parent
      return {
        testSuiteId: node,
        parentId: parent
      }
    })
  }
  if (caseList.value.length) {
    planCases = caseList.value.map((c) => {
      return {
        testUserId: c.testUserId,
        testCaseId: c.id
      }
    })
  } else {
    planCases = params.caseIds.map((c) => {
      return {
        testUserId: testUserObj.value[c.caseId],
        testCaseId: c.caseId
      }
    })
  }
  return { planSuites, planCases }
}
</script>
<style scoped lang="scss">
.form-inline .el-input {
  --el-input-width: 240px;
}

.form-inline .el-select {
  --el-select-width: 240px;
}

.form-inline .el-date-editor {
  --el-date-editor-width: 240px;
}

:deep(.el-date-editor.el-input, .el-date-editor.el-input__wrapper) {
  width: 240px;
}
</style>
